package szc.common.code.tool;

import szc.common.code.counter.NoValidCodeLineCounter;
import szc.common.code.counter.ValidCodeLineCounter;
import szc.common.code.enums.FileTypeEnum;
import szc.common.code.rule.*;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;

/**
 * @desc 文件代码统计
 * @author songzc
 * @date 2022/6/18
 */
public class FileCodeCount {

    // 有效程序行数
    protected int normalLines = 0;
    // 空白行数
    protected int whiteLines = 0;
    // 注释行数
    protected int commentLines = 0;

    // 代码文件
    protected File sourceCodeFile = null;

    // 文件类型
    protected FileTypeEnum fileTypeEnum;

    // 有效代码解析器（通用）
    protected ValidCodeLineCounter validCounter = new ValidCodeLineCounter();

    // 无效代码解析器（自定义）
    protected NoValidCodeLineCounter noValidCounter;

    public FileCodeCount(FileTypeEnum fileTypeEnum) throws Exception {
        this.fileTypeEnum = fileTypeEnum;
        this.noValidCounter = buildNoValidCounter();
    }

    public void setSourceCodeFile(File sourceCodeFile) throws Exception {
        if (sourceCodeFile == null) {
            throw new Exception("source code file can not be null");
        }
        this.sourceCodeFile = sourceCodeFile;
    }

    /**
     * 无效代码解析器(可自定义)
     */
    public final NoValidCodeLineCounter buildNoValidCounter() {
        List<CodeLineParserAbstract> noValidCodeLineParserGroup = new LinkedList<CodeLineParserAbstract>();
        // 添加空行解析器
        noValidCodeLineParserGroup.add(new WhiteCodeLineParser());
        // 添加单行注释解析器
        if(fileTypeEnum.getSingleComment() !=null){
            noValidCodeLineParserGroup.add(new SingleCommentCodeLineParser(fileTypeEnum));
        }
        // 添加多行注释解析器
        MultipleEndCommentCodeLineParser endParser = new MultipleEndCommentCodeLineParser(fileTypeEnum);
        MultipleStartCommentCodeLineParser startParser = new MultipleStartCommentCodeLineParser(fileTypeEnum);
        MultipleMiddleCommentCodeLineParser middleParser = new MultipleMiddleCommentCodeLineParser();
        // 识别多行注释中间行
        endParser.addStatusWatcher(middleParser);
        startParser.addStatusWatcher(middleParser);
        noValidCodeLineParserGroup.add(endParser);
        noValidCodeLineParserGroup.add(startParser);
        noValidCodeLineParserGroup.add(middleParser);
        return new NoValidCodeLineCounter(noValidCodeLineParserGroup);
    }

    /**
     * 统计规则(可自定义)
     */
    public void countByRules() {
        try (BufferedReader fileLineReader = new BufferedReader(new FileReader(this.sourceCodeFile))){
            String lineContent;
            while ((lineContent = fileLineReader.readLine()) != null) {
                this.noValidCounter.countNoValidCodeLine(lineContent);
                if (!this.noValidCounter.isNoValidCodeLine()) {
                    this.validCounter.countValidCodeLine(lineContent);
                }
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public int getNormalLineCount() {
        return this.validCounter.getLineCount();
    }

    public int getWhiteLineCount() {
        return 0;
    }

    public int getCommentLineCount() {
        return 0;
    }

    public int getAllLineCount() {
        return this.validCounter.getLineCount() + this.noValidCounter.getLineCount();
    }

}